/*!
*
* \file    FrameDemuxer.c
*
* \brief    Demuxer c file.
*
* Header file of the functions declaration about MIRA CMMB Demuxer
*
* \par    Include files
* - CmmbDemuxer.h
*
* \par    Copyright (c) 2008 Maxscend Technologies Inc. All rights reserved
*
* PROPRIETARY RIGHTS of Maxscend Technologies Inc. are involved in
* the subject matter of this material.  All manufacturing, reproduction,
* use, and sales rights pertaining to this subject matter are governed
* by the license agreement.  The recipient of this software implicitly
* accepts the terms of the license.
*
* \version
* Revision of last commit: $Rev: 1003 $
* Author of last commit  : $Author: maxscend\chaohui.jiang $
* Date of last commit    : $Date: 2011-01-05 16:31:57 +0800 (星期三, 05 一月 2011) $
*
*/

#include "Mxd0250API.h"
#include "Mxd0250Private.h"
#include "Mxd0250Frame.h"

MXD_UINT32 _mxd_CalcCRC32(const MXD_UINT8* inData, MXD_INT32 inLen);
MXD_UINT8 _mxd_CalcCRC8(const MXD_UINT8* pbuf, MXD_INT32 len);

typedef MXD_INT32 ( *DecomposeFunc)( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nStartBit  );
typedef MXD_BOOL ( *VerifyFunc)( CMMBUNIT_DEFINE* pThis );

MXD_INT32 ContainerDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  );
MXD_INT32 SimpleNodeDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  );
MXD_INT32 PlaceholderDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  );

MXD_BOOL FrameHeader_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SubFramesLength_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL NextFrameParam_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL StartTimeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DataSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DataSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL BitRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DisplayCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ResolutionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FrameRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioBitRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SampleRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DescriptionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SubFrames_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ControlTables_PreDecompose( CMMBUNIT_DEFINE* pThis );



MXD_BOOL NIT_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SystemTime_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL NetName_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL OtherFreqInfo_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL OtherNetInfo_PreDecompose( CMMBUNIT_DEFINE* pThis );

MXD_BOOL ServiceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL TimeSlots_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SubFramesInfo_PreDecompose( CMMBUNIT_DEFINE* pThis );

MXD_BOOL FrameHeader_Verify( CMMBUNIT_DEFINE* pThis );
MXD_BOOL SubFrameHeader_Verify( CMMBUNIT_DEFINE* pThis );

MXD_BOOL FrameHeader_PostDecompose( CMMBUNIT_DEFINE* pThis );

MXD_BOOL ShortServiceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ESGSeviceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ESGDataTypes_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ESGDataSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL CAS_SectionInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EmergencyMsgSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EmergencyMsgData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EmergencyMsgData_PostDecompose( CMMBUNIT_DEFINE* pThis );

MXD_BOOL EmergencyMsgBodyCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EmgSendTime_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL MsgDetailCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ExtendMsgs_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ExtendMsgData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL MsgText_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InstitutionDetailCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ReferenceServiceIdc_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InstitutionName_PreDecompose( CMMBUNIT_DEFINE* pThis );



MXD_BOOL VideoSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InnoVideoFragment_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawVideoSlices_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawVideoSlice_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InnoVideoPackets_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL PlayTimeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoAuHeader_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioAuHeader_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioNewHeader_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RtpNalPacketCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RtpNalPacketCtn_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawH264_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL NalUnitData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL NalUnitData_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FU_Data_PreDecompose( CMMBUNIT_DEFINE* pThis );

#ifndef USE_EXTERNAL_DEMUXER

MXD_BOOL AudioSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioSectionHeader_Verify( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InnoAudioPacket_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAacCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAacSize_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAacSize_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAacData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAacData_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DataSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DataSlices_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL DataSectionHeader_Verify( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ProgramHint_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EsgDataSection_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL XpeDataSection_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL OtherDataSlice_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL CmmbProgramHint_Start_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ProgramHintRecords_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL HintStartTime_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ProgramHintSubjects_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL ProgramHintSubject_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL InnoEsgDataHeader_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL EsgDataSlice_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoPlayTimeCtn_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudioSlices_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudioCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudioSize_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudioSize_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudio_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL RawAudio_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL VideoCrc8_PostDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL AudioCrc8_PostDecompose( CMMBUNIT_DEFINE* pThis );

MXD_BOOL VideoSectionHeader_Verify( CMMBUNIT_DEFINE* pThis );

MXD_BOOL CmmbXpe_Start_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL TotalPacketLen_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL PayloadTypeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FecTypeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL XpePayloadCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL XpePacket_Verify( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FecParam_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FecData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL StreamData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FileSliceCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FatSliceCtn_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FileData_PreDecompose( CMMBUNIT_DEFINE* pThis );
MXD_BOOL FatData_PreDecompose( CMMBUNIT_DEFINE* pThis );

#endif //USE_EXTERNAL_DEMUXER

static CMMBUNIT_DEFINE CmmbEmpty[]= 
{
	{ "Unknown", 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbTopFrame[]= 
{
	{"FrameHeader", 0 /*Preset*/, ContainerDecompose, FrameHeader_PreDecompose, FrameHeader_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ControlTables", 0 /*Preset*/, ContainerDecompose, ControlTables_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFrames", 0 /*Preset*/, ContainerDecompose, SubFrames_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFrameHeader[]= 
{
	{"FrameStartCode", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FrameHeaderLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ProtocolVer", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ProtocolLowVer", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"MF_ID", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyFlag", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NextFrameIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ContTabAhead", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NIT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CMCT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CSCT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SMCT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SSCT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESG_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExpandTabNo", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFrameCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFramesLengthCtn", 0 /*Preset*/, ContainerDecompose, SubFramesLength_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NextFrameParamCtn", 0 /*Preset*/, ContainerDecompose, NextFrameParam_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, FrameHeader_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbNextFrameParam[]= 
{
	{"FrameHeaderLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFrame1Length", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFrame1HeaderLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSubFrameLength[]= 
{
	{"SubFrameLength", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSubFrame[]= 
{
	{"SubFrameHeaderLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"StartTimeFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoSectionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioSectionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSectionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExpandAreaFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisturbFlag", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"StartTimeCtn", 0 /*Preset*/, ContainerDecompose, StartTimeCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoSectionsInfoCtn", 0 /*Preset*/, ContainerDecompose, VideoSectionsInfoCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioSectionsInfoCtn", 0 /*Preset*/, ContainerDecompose, AudioSectionsInfoCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSectionsInfoCtn", 0 /*Preset*/, ContainerDecompose, DataSectionsInfoCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoInfos", 0 /*Preset*/, ContainerDecompose, VideoInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioInfos", 0 /*Preset*/, ContainerDecompose, AudioInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, SubFrameHeader_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoSectionCtn", 0 /*Preset*/, ContainerDecompose, VideoSectionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioSectionCtn", 0 /*Preset*/, ContainerDecompose, AudioSectionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSectionCtn", 0 /*Preset*/, ContainerDecompose, DataSectionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbStartTime[]= 
{
	{"StartTime", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoSectionsInfo[]= 
{
	{"VideoSectionsLength", 21 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoStreamCount", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioSectionsInfo[]= 
{
	{"AudioSectionsLength", 21 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioStreamCount", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDataSectionsInfo[]= 
{
	{"DataSectionsLength", 21 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ECM_Flag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoInfo[]= 
{
	{"VideoCodecType", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BitRateFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisplayFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ResolutionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FrameRateFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BitRateCtn", 0 /*Preset*/, ContainerDecompose, BitRateCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisplayCtn", 0 /*Preset*/, ContainerDecompose, DisplayCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ResolutionCtn", 0 /*Preset*/, ContainerDecompose, ResolutionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FrameRateCtn", 0 /*Preset*/, ContainerDecompose, FrameRateCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoBitRate[]= 
{
	{"BitRate", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDisplay[]= 
{
	{"DisplayStartPointX", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisplayStartPointY", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisplayPriority", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve1", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbResolution[]= 
{
	{"Reserve2", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ResolutionX", 10 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ResolutionY", 10 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFrameRate[]= 
{
	{"FrameRate", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve3", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioInfo[]= 
{
	{"AudioCodecType", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BitRateFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SampleRateFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DescriptionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BitRateCtn", 0 /*Preset*/, ContainerDecompose, AudioBitRateCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SampleRateCtn", 0 /*Preset*/, ContainerDecompose, SampleRateCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DescriptionCtn", 0 /*Preset*/, ContainerDecompose, DescriptionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioBitRate[]= 
{
	{"BitRate", 14 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve1", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSampleRate[]= 
{
	{"Reserve2", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SampleRate", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDescription[]= 
{
	{"Description", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbControlTab[]= 
{
	{"NIT", 0 /*Preset*/, ContainerDecompose, NIT_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CMCT", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CSCT", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SMCT", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SSCT", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGTab", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CASTab", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyTab", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CorruptData", 0 /*Preset*/, PlaceholderDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbNIT[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NIT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SystemTime", 0 /*Preset*/, ContainerDecompose, SystemTime_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Country", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetLevel", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetNo", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetNameLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetName", 0 /*Preset*/, PlaceholderDecompose, NetName_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Freq", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BandWidth", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FreqCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherFreqInfo", 0 /*Preset*/, ContainerDecompose, OtherFreqInfo_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetInfo", 0 /*Preset*/, ContainerDecompose, OtherNetInfo_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbOtherFreqInfo[]= 
{
	{"OtherFreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherFreq", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherBandWidth", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbOtherNetInfo[]= 
{
	{"OtherNetLevel", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetNo", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetFreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetFreq", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherNetBandWidth", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbCMCT_SMCT[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CMCT_SMCT_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ServiceInfoCount", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ServiceInfos", 0 /*Preset*/, ContainerDecompose, ServiceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbServiceInfo[]= 
{
	{"MF_ID", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RS_CodeRate", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InterleaveMode", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LDPC_CodeRate", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ModulateMode", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DisturbMode", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TimeSlotCount", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TimeSlots", 0 /*Preset*/, ContainerDecompose, TimeSlots_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve1", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFrameCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubFramesInfo", 0 /*Preset*/, ContainerDecompose, SubFramesInfo_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbTimeSlot[]= 
{
	{"TimeSlotNo", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSubFrameInfo[]= 
{
	{"SubFrameNo", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ServiceID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbCSCT_SSCT[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionCount", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CSCT_SSCTNo", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ShortServiceInfoCount", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ShortServiceInfos", 0 /*Preset*/, ContainerDecompose, ShortServiceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbShortServiceInfo[]= 
{
	{"ServiceID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbESGTab[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESG_No", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionLength", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionNo", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetLevel", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetNo", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve1", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LocalTime", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TextCodec", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGSeviceCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGSeviceInfos", 0 /*Preset*/, ContainerDecompose, ESGSeviceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve2", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGDataTypeCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGDataTypes", 0 /*Preset*/, ContainerDecompose, ESGDataTypes_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbESGSeviceInfo[]= 
{
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGSeviceIndexID", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGSeviceID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbESGDataType[]= 
{
	{"ESGDataTypeID", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGDataSliceCount", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGDataSliceInfos", 0 /*Preset*/, ContainerDecompose, ESGDataSliceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbESGDataSliceInfo[]= 
{
	{"ESGDataSliceID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGDataSliceVersion", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ESGSeviceIndexID", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbCASTab[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 20 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"UpdateNumber", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionNumber", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SectionQuantity", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CAS_SectionInfos", 0 /*Preset*/, ContainerDecompose, CAS_SectionInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbCAS_SectionInfo[]= 
{
	{"CA_System_ID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Service_ID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EMM_Data_Type", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ECM_Data_Type", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ECM_Transport_Type", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserved", 30 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbEmergencyTab[]= 
{
	{"TableID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InterMsgCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyNo", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyMsgSectionLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyMsgSectionCtn", 0 /*Preset*/, ContainerDecompose, EmergencyMsgSectionCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbEmergencyMsgSection[]= 
{
	{"ProtocolVer", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LowProtocolVer", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetLevel", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetNo", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"MsgID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CurrentSectionNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LastSectionNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"MsgLength", 13 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyMsgData", 0 /*Preset*/, PlaceholderDecompose, EmergencyMsgData_PreDecompose, EmergencyMsgData_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSystemTime[]= 
{
	{"MJD_Date", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BCD_Time", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbPayloadType[]= 
{
	{"PayloadType", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 7 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};


#ifndef USE_EXTERNAL_DEMUXER

static CMMBUNIT_DEFINE CmmbVideoSection[]= 
{
	{"VideoSectionHeaderLength", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoSliceInfos", 0 /*Preset*/, ContainerDecompose, VideoSliceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, VideoSectionHeader_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoVideoPackets", 0 /*Preset*/, ContainerDecompose, InnoVideoPackets_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RawVideoSlices", 0 /*Preset*/, ContainerDecompose, RawVideoSlices_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbInnoVideoPacket[]= 
{
	{"InnoVideoFragments", 0 /*Preset*/, ContainerDecompose, InnoVideoFragment_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbRawVideoSlice[]= 
{
	{"RawVideoSlice", 0 /*Preset*/, PlaceholderDecompose, RawVideoSlice_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoSliceInfo[]= 
{
	{"VideoSliceLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FrameType", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"StreamNo", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FrameEndFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"PlayTimeFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"PlayTimeCtn", 0 /*Preset*/, ContainerDecompose, PlayTimeCtn_PreDecompose, VideoPlayTimeCtn_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoPlayTime[]= 
{
	{"PlayTime", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbInnoVideoFragment[]= 
{
	{"InnoStartByte", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoEndIdc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketType", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoCrc8", 8 /*Preset*/, SimpleNodeDecompose, NULL, VideoCrc8_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{"VideoAuHeader", 0 /*Preset*/, ContainerDecompose, VideoAuHeader_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Forbidden_zero_bit", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Nal_ref_idc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Type", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RtpNalPacketCtn", 0 /*Preset*/, ContainerDecompose, RtpNalPacketCtn_PreDecompose, RtpNalPacketCtn_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbVideoAuHeader[]= 
{
	{"HeaderLen", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"IV", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"KeyId", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RFU", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbH264Packet[]= 
{
	{"RawH264", 0 /*Preset*/, PlaceholderDecompose, RawH264_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbSTAP_A_Packet[]= 
{
	{"NalUnitSize", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NalUnitData", 0 /*Preset*/, PlaceholderDecompose, NalUnitData_PreDecompose, NalUnitData_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFU_A_Packet[]= 
{
	{"StartBitIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EndBitIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Ignore", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FU_Type", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FU_Data", 0 /*Preset*/, PlaceholderDecompose, FU_Data_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioSection[]= 
{
	{"AudioSliceCount", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioSliceInfos", 0 /*Preset*/, ContainerDecompose, AudioSliceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, AudioSectionHeader_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoAudioPacket", 0 /*Preset*/, ContainerDecompose, InnoAudioPacket_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RawAudioSlices", 0 /*Preset*/, ContainerDecompose, RawAudioSlices_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioSliceInfo[]= 
{
	{"AudioSliceLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioStreamNo", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"PlayTime", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbRawAudioPacket[]= 
{
	{"RawAudioCtn", 0 /*Preset*/, ContainerDecompose, RawAudioCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbRawAudioSlice[]= 
{
	{"RawAudioSize", 8 /*Preset*/, SimpleNodeDecompose, RawAudioSize_PreDecompose, RawAudioSize_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RawAudio", 0 /*Preset*/, PlaceholderDecompose, RawAudio_PreDecompose, RawAudio_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbInnoAudioPacket[]= 
{
	{"InnoStartByte", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoEndIdc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketType", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoCrc8", 8 /*Preset*/, SimpleNodeDecompose, NULL, AudioCrc8_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioAuHeader", 0 /*Preset*/, ContainerDecompose, AudioAuHeader_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"AudioNewHeader", 0 /*Preset*/, ContainerDecompose, AudioNewHeader_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RawAacCtn", 0 /*Preset*/, ContainerDecompose, RawAacCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioAuHeader[]= 
{
	{"HeaderLen", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"IV", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"KeyId", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RFU", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbAudioNewHeader[]= 
{
	{"UnknowHeader", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbRawAac_Packet[]= 
{
	{"RawAacSize", 8 /*Preset*/, SimpleNodeDecompose, RawAacSize_PreDecompose, RawAacSize_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RawAacData", 0 /*Preset*/, PlaceholderDecompose, RawAacData_PreDecompose, RawAacData_PostDecompose, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDataSection[]= 
{
	{"DataSliceCount", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSliceInfos", 0 /*Preset*/, ContainerDecompose, DataSliceInfos_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, DataSectionHeader_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSlices", 0 /*Preset*/, ContainerDecompose, DataSlices_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDataSlice[]= 
{
	{"ProgramHint", 0 /*Preset*/, ContainerDecompose, ProgramHint_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EsgDataSection", 0 /*Preset*/, ContainerDecompose, EsgDataSection_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"XpeDataSection", 0 /*Preset*/, ContainerDecompose, XpeDataSection_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"OtherDataSlice", 0 /*Preset*/, PlaceholderDecompose, OtherDataSlice_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbDataSliceInfo[]= 
{
	{"DataSliceType", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataSliceLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbProgramHint[]= 
{
	{"InnoStartByte", 8 /*Preset*/, SimpleNodeDecompose, CmmbProgramHint_Start_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoEndIdc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketType", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoCrc8", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"UnknownFlag", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"RecordCount", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 6 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ProgramHintRecords", 0 /*Preset*/, ContainerDecompose, ProgramHintRecords_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbProgramHintRecord[]= 
{
	{"StartTime", 0 /*Preset*/, ContainerDecompose, HintStartTime_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Duration", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LangType", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SubjectLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ProgramHintSubject", 0 /*Preset*/, PlaceholderDecompose, ProgramHintSubject_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbEsgDataSection[]= 
{
	{"InnoEsgDataHeader", 0 /*Preset*/, ContainerDecompose, InnoEsgDataHeader_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EsgDataBlockID", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EsgDataTypeID", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ZipType", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BlockNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BlockCount", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SliceLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EsgDataSlice", 0 /*Preset*/, PlaceholderDecompose, EsgDataSlice_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbInnoEsgDataHeader[]= 
{
	{"InnoStartByte", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoEndIdc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketType", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoCrc16", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbXpePacket[]= 
{
	{"InnoStartByte", 8 /*Preset*/, SimpleNodeDecompose, CmmbXpe_Start_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoEndIdc", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketType", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoPacketLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InnoCrc8", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"UnknownFlag", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"StartFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EndFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"IsFecIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"HaveFecIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"PayloadLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"CrcIdc", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TransmitNo", 7 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TotalPacketLen", 16 /*Preset*/, SimpleNodeDecompose, TotalPacketLen_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"PayloadTypeCtn", 0 /*Preset*/, ContainerDecompose, PayloadTypeCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FecTypeCtn", 0 /*Preset*/, ContainerDecompose, FecTypeCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc8", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"XpePayloadCtn", 0 /*Preset*/, ContainerDecompose, XpePayloadCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 0 /*Preset*/, SimpleNodeDecompose, NULL, XpePacket_Verify, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFecType[]= 
{
	{"FecType", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FecParamLen", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FecParam", 0 /*Preset*/, PlaceholderDecompose, FecParam_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbXpePayload[]= 
{
	{"FecData", 0 /*Preset*/, PlaceholderDecompose, FecData_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FileSliceCtn", 0 /*Preset*/, ContainerDecompose, FileSliceCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FatSliceCtn", 0 /*Preset*/, ContainerDecompose, FatSliceCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"StreamData", 0 /*Preset*/, PlaceholderDecompose, StreamData_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFileSlice[]= 
{
	{"ResourceID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"BlockNo", 10 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SliceNo", 14 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ReflashNo", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FileData", 0 /*Preset*/, PlaceholderDecompose, FileData_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbFatSlice[]= 
{
	{"ResourceID", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SliceNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ReflashNo", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ZipType", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LastSliceNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SliceLen", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FatData", 0 /*Preset*/, PlaceholderDecompose, FatData_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Crc32", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

#endif //USE_EXTERNAL_DEMUXER

/**********************************************************************************************************/

static CMMBUNIT_DEFINE CmmbEmergencyMsg[]= 
{
	{"EmergencyMsgBodyCtn", 0 /*Preset*/, ContainerDecompose, EmergencyMsgBodyCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"EmergencyMsgTrigerCtn", 0 /*Preset*/, ContainerDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbEmergencyMsgBody[]= 
{
	{"Triger", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Type", 7 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Level", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Codec", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"SendTime", 0 /*Preset*/, ContainerDecompose, EmgSendTime_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Duration", 20 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"LangCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"MsgDetailCtn", 0 /*Preset*/, ContainerDecompose, MsgDetailCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve1", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExtendMsgCount", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExtendMsgs", 0 /*Preset*/, ContainerDecompose, ExtendMsgs_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbExtendEmergencyMsg[]= 
{
	{"DataType", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"DataLength", 16 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExtendMsgData", 0 /*Preset*/, PlaceholderDecompose, ExtendMsgData_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbMsgDetail[]= 
{
	{"LangType", 24 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InstitutionFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ReferenceServiceFlag", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 2 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"TextLength", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"MsgText", 0 /*Preset*/, PlaceholderDecompose, MsgText_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InstitutionDetailCtn", 0 /*Preset*/, ContainerDecompose, InstitutionDetailCtn_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ReferenceServiceIdc", 16 /*Preset*/, SimpleNodeDecompose, ReferenceServiceIdc_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"ExtendMsgIndex", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbInstitutionDetail[]= 
{
	{"NameLength", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"InstitutionName", 0 /*Preset*/, PlaceholderDecompose, InstitutionName_PreDecompose, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

static CMMBUNIT_DEFINE CmmbEmergencyMsgTriger[]= 
{
	{"Triger", 1 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Type", 7 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Level", 3 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 5 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetLevel", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetNo", 12 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetFreqNo", 8 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"NetFreq", 32 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"FreqBandWidth", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{"Reserve", 4 /*Preset*/, SimpleNodeDecompose, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
	{NULL, 0 /*Preset*/, NULL, NULL, NULL, NULL, NULL,  TRUE, 0, NULL, 0},
};

/****************************************************************************************************/

#ifndef CMMBUNIT_STORAGE_UNITLIST_LEN
#define CMMBUNIT_STORAGE_UNITLIST_LEN 50
#endif

#ifndef CMMBUNIT_STORAGE_UNITLIST_ARRAY_LEN
#define CMMBUNIT_STORAGE_UNITLIST_ARRAY_LEN 80
#endif

typedef struct _CMMBUNIT_STORAGE
{
	CMMBUNIT_DEFINE* m_pUnitListArray[CMMBUNIT_STORAGE_UNITLIST_ARRAY_LEN];
	MXD_UINT16 m_nTailUnitListIndex;
	MXD_UINT16 m_nTailUnitIndex;
}CMMBUNIT_STORAGE;

static CMMBUNIT_STORAGE sGlobalStorage;

void InitUnitListStorage( )
{
	MXD_Memset( &sGlobalStorage, 0, sizeof(CMMBUNIT_STORAGE) );

	sGlobalStorage.m_pUnitListArray[0] = (CMMBUNIT_DEFINE*) MXD_Malloc( sizeof(CMMBUNIT_DEFINE) * CMMBUNIT_STORAGE_UNITLIST_LEN );
}

CMMBUNIT_DEFINE* AllocNewUnitList( MXD_UINT16 nListLen  )
{
	MXD_UINT16 nIndex;
	if( sGlobalStorage.m_nTailUnitListIndex == CMMBUNIT_STORAGE_UNITLIST_ARRAY_LEN - 1 )
	{
		MXD_DebugPrint( "AllocNewUnitList return NULL\n" );
		return NULL;
	}
	if( nListLen > CMMBUNIT_STORAGE_UNITLIST_LEN )
	{
		sGlobalStorage.m_pUnitListArray[ ++sGlobalStorage.m_nTailUnitListIndex ] = (CMMBUNIT_DEFINE*) MXD_Malloc( sizeof(CMMBUNIT_DEFINE) * nListLen * 2 );
		sGlobalStorage.m_nTailUnitIndex = nListLen;
		//MXD_DebugPrint( "1m_nTailUnitListIndex %d, m_nTailUnitIndex %d \n", sGlobalStorage.m_nTailUnitListIndex, sGlobalStorage.m_nTailUnitIndex );
		return sGlobalStorage.m_pUnitListArray[sGlobalStorage.m_nTailUnitListIndex];
	}
	else if( nListLen >= CMMBUNIT_STORAGE_UNITLIST_LEN - sGlobalStorage.m_nTailUnitIndex )
	{
		sGlobalStorage.m_pUnitListArray[ ++sGlobalStorage.m_nTailUnitListIndex ] = (CMMBUNIT_DEFINE*) MXD_Malloc( sizeof(CMMBUNIT_DEFINE) * (nListLen>CMMBUNIT_STORAGE_UNITLIST_LEN ? nListLen : CMMBUNIT_STORAGE_UNITLIST_LEN) );
		sGlobalStorage.m_nTailUnitIndex = nListLen;
		//MXD_DebugPrint( "2m_nTailUnitListIndex %d, m_nTailUnitIndex %d \n", sGlobalStorage.m_nTailUnitListIndex, sGlobalStorage.m_nTailUnitIndex );
		return sGlobalStorage.m_pUnitListArray[sGlobalStorage.m_nTailUnitListIndex];
	}	 
	else
	{
		nIndex = sGlobalStorage.m_nTailUnitIndex;
		sGlobalStorage.m_nTailUnitIndex += nListLen;
		//MXD_DebugPrint( "3m_nTailUnitListIndex %d, m_nTailUnitIndex %d \n", sGlobalStorage.m_nTailUnitListIndex, sGlobalStorage.m_nTailUnitIndex );
		return sGlobalStorage.m_pUnitListArray[sGlobalStorage.m_nTailUnitListIndex] + nIndex;
	}
}

void ClearUnitListStorage( )
{
	MXD_UINT16 i;
	for( i=0; i<CMMBUNIT_STORAGE_UNITLIST_ARRAY_LEN; i++ )
		if( sGlobalStorage.m_pUnitListArray[i] )
		{
			if (sGlobalStorage.m_pUnitListArray[i])
				MXD_Free( sGlobalStorage.m_pUnitListArray[i] );
			sGlobalStorage.m_pUnitListArray[i] = 0;
		}
		sGlobalStorage.m_nTailUnitListIndex = 0;
		sGlobalStorage.m_nTailUnitIndex = 0;
}

/****************************************************************************************************/

CMMBUNIT_DEFINE* CreateUnitList( CMMBUNIT_DEFINE* pTemplateUnitTab, MXD_UINT32 nCount, CMMBUNIT_DEFINE* m_pParentUnit )
{
	CMMBUNIT_DEFINE* pNewList;
	CMMBUNIT_DEFINE* pTmpNode;
	MXD_UINT32 nTemplateTabLen = 1;
	MXD_UINT32 i,j;

	//MXD_DebugPrint("create name--->%s %d\n", pTemplateUnitTab->m_szNodeName, nCount);
	if( nCount == 0 )
		return NULL;

	for( pTmpNode=pTemplateUnitTab; pTmpNode->m_szNodeName; pTmpNode++ )
		nTemplateTabLen++;

	pNewList = AllocNewUnitList( nTemplateTabLen * nCount );
	if (NULL == pNewList)
	{
		MXD_DebugPrint("Create new list fail! is that unit storage not big enough?\n" );
		return NULL;
	}

	for( i=0; i<nCount; i++ )
	{
		MXD_Memcpy((MXD_UINT8*)(pNewList + i*nTemplateTabLen), (MXD_UINT8*)pTemplateUnitTab, sizeof(CMMBUNIT_DEFINE) * nTemplateTabLen);
		for( j=0; j<nTemplateTabLen; j++ )
		{
			if( pNewList[i*nTemplateTabLen+j].m_szNodeName )
				pNewList[i*nTemplateTabLen+j].m_u2.m_pParentUnit = m_pParentUnit;
		}
		if( i<=nCount-2 && nCount>1 )
			pNewList[(i+1)*nTemplateTabLen-1].m_u2.m_pNextUnitList = &pNewList[(i+1)*nTemplateTabLen];
		if( i>=1 )
			pNewList[(i+1)*nTemplateTabLen-1].m_u1.m_pPrevUnitList = &pNewList[i*nTemplateTabLen];
	}

	return pNewList;
}

CMMBUNIT_DEFINE* CloneUnitList( CMMBUNIT_DEFINE* pTemplateUnitTab )
{
	CMMBUNIT_DEFINE* pNewList;
	CMMBUNIT_DEFINE* pTmpNode;
	MXD_UINT32 nTemplateTabLen = 1;

	for( pTmpNode=pTemplateUnitTab; pTmpNode->m_szNodeName; pTmpNode++ )
		nTemplateTabLen++;

	pNewList = AllocNewUnitList( nTemplateTabLen );

	if (NULL == pNewList)
		return NULL;

	MXD_Memcpy( (MXD_UINT8*)pNewList, (MXD_UINT8*)pTemplateUnitTab, sizeof(CMMBUNIT_DEFINE) * nTemplateTabLen );

	return pNewList;
}

CMMBUNIT_DEFINE* FindUnitFromList( CMMBUNIT_DEFINE* pUnitList, const MXD_INT8* pUnitName )
{
	CMMBUNIT_DEFINE* pTmpNode;

	if( !pUnitList )
		return CmmbEmpty;
	for( pTmpNode=pUnitList; pTmpNode->m_szNodeName; pTmpNode++ )
	{
		if( MXD_Strcmp( pTmpNode->m_szNodeName, pUnitName ) == 0 )
			return pTmpNode;
	}
	return CmmbEmpty;
}

CMMBUNIT_DEFINE* FindUnitFromChild( CMMBUNIT_DEFINE* pUnitNode, const MXD_INT8* pUnitName )
{
	return FindUnitFromList( pUnitNode->m_u1.m_pChildUnitList, pUnitName );
}

CMMBUNIT_DEFINE* GetEndUnitOfList( CMMBUNIT_DEFINE* pUnitList )
{
	CMMBUNIT_DEFINE* pTmpNode = pUnitList;

	if( !pTmpNode )
		return NULL;

	while (pTmpNode->m_szNodeName)
		pTmpNode++;

	return pTmpNode;
}

CMMBUNIT_DEFINE* GetNextSiblingInList(CMMBUNIT_DEFINE* pUnitList)
{
	CMMBUNIT_DEFINE* pTmpNode = GetEndUnitOfList(pUnitList);
	if( !pTmpNode )
		return NULL;
	else
		return pTmpNode->m_u2.m_pNextUnitList;
}

MXD_UINT32 GetLinkedUnitListCount( CMMBUNIT_DEFINE* pLinkedList )
{
	CMMBUNIT_DEFINE *pEndUnit, *pList = pLinkedList;
	MXD_UINT32 nCount = 0;

	while( pList )
	{
		nCount++;
		pEndUnit = GetEndUnitOfList( pList );
		pList = pEndUnit->m_u2.m_pNextUnitList;
	}
	return nCount;
}

CMMBUNIT_DEFINE* GetHeaderItemFromLinkedUnitList( CMMBUNIT_DEFINE* pLinkedList, MXD_UINT32 nIndex )
{
	CMMBUNIT_DEFINE *pEndUnit, *pList = pLinkedList;
	MXD_UINT32 nCount = 0;

	while( pList )
	{
		if( nCount++ == nIndex )
			return pList;
		pEndUnit = GetEndUnitOfList( pList );
		if( !pEndUnit )
			break;
		pList = pEndUnit->m_u2.m_pNextUnitList;
	}
	return NULL;
}

CMMBUNIT_DEFINE* GetUnitFromLinkedUnitList( CMMBUNIT_DEFINE* pLinkedList, MXD_UINT32 nIndex, const MXD_INT8* pUnitName )
{
	CMMBUNIT_DEFINE *pEndUnit, *pUnit, *pList = pLinkedList;
	MXD_UINT32 nCount = 0;

	while( pList )
	{
		if( nCount++ == nIndex )
		{
			pUnit = pList;
			while( pUnit->m_szNodeName )
			{
				if( MXD_Strcmp( pUnit->m_szNodeName, pUnitName ) == 0 )
					return pUnit;
				pUnit++;
			}
			return NULL;
		}
		pEndUnit = GetEndUnitOfList( pList );
		if( !pEndUnit )
			return NULL;
		pList = pEndUnit->m_u2.m_pNextUnitList;
	}
	return NULL;
}

MXD_UINT32 FindMyIndexFromLinkedUnitList( CMMBUNIT_DEFINE* pLinkedList, CMMBUNIT_DEFINE* pMyUnit )
{
	CMMBUNIT_DEFINE *pUnit, *pList = pLinkedList;
	MXD_UINT32 nIndex = 0;

	while( pList )
	{
		pUnit = pList;
		while( pUnit->m_szNodeName )
		{
			if( pUnit == pMyUnit )
				return nIndex;
			pUnit++;
		}
		pList = pUnit->m_u2.m_pNextUnitList;
		nIndex++;
	}
	return nIndex;
}

/****************************************************************************************************/

MXD_INT32 SimpleNodeDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  )
{
	MXD_UINT32 i,j,k,nValueStartBit;
	MXD_UINT8* pContentNow= pContent, *pValue = (MXD_UINT8*)&pThis->m_nValue;
	MXD_UINT32 nRes = 0;

	if( !pThis->m_bActive )
		return 0;

	// out of bound?
	if( pThis->m_nPresetNodeBits/8 > nContentLen || nContentLen == 0 )
	{
		pThis->m_bActive = 0;
		return 0;
	}

	pThis->m_pContent = pContent;

	if( pThis->fnPreDecompose )
	{
		if( ! pThis->fnPreDecompose( pThis ) )
			return -1;
	}

	// predecompse may change the active flag.
	if( !pThis->m_bActive )
		return 0;

	// check out of bound again.
	if( pThis->m_nPresetNodeBits/8 > nContentLen || nContentLen == 0 )
	{
		pThis->m_bActive = 0;
		return 0;
	}

	pThis->m_nValue = 0;

	nValueStartBit = (pThis->m_nPresetNodeBits <= 8) ? (8 - pThis->m_nPresetNodeBits) : (32 - pThis->m_nPresetNodeBits);

	for( i=0,j=nStartBit,k=nValueStartBit; i<pThis->m_nPresetNodeBits; i++,j++,k++ )
	{
		if( j > 7 )
		{
			pContentNow += j/8;
			j = j%8;
		}
		if( k > 7 )
		{
			pValue += k/8;
			k = k%8;
		}
		if( (*pContentNow) & (0x1 << (7-j)) )
			*pValue |= 0x1 << (7-k);
		else
			*pValue &= ~(0x1 << (7-k));
	}

	if( pThis->m_nPresetNodeBits > 8 )
	{
		((MXD_UINT8*)&nRes)[0] = ((MXD_UINT8*)&pThis->m_nValue)[3];
		((MXD_UINT8*)&nRes)[1] = ((MXD_UINT8*)&pThis->m_nValue)[2];
		((MXD_UINT8*)&nRes)[2] = ((MXD_UINT8*)&pThis->m_nValue)[1];
		((MXD_UINT8*)&nRes)[3] = ((MXD_UINT8*)&pThis->m_nValue)[0];
		pThis->m_nValue = nRes;
	}

	pThis->m_nContentBitLen = pThis->m_nPresetNodeBits;

	if( pThis->fnPostDecompose )
	{
		if( ! pThis->fnPostDecompose( pThis ) )
			return -1;
	}

	return pThis->m_nPresetNodeBits;
}

MXD_INT32 PlaceholderDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  )
{
	if( !pThis->m_bActive )
		return 0;

	// out of bound?
	if( pThis->m_nPresetNodeBits/8 > nContentLen || nContentLen == 0 )
	{
		pThis->m_bActive = 0;
		return 0;
	}

	pThis->m_pContent = pContent;
	pThis->m_nContentBitLen = nContentLen*8;

	if( pThis->fnPreDecompose )
	{
		if( ! pThis->fnPreDecompose( pThis ) )
			return -1;
	}

	// predecompse may change the active flag.
	if( !pThis->m_bActive )
		return 0;

	// check out of bound again.
	if( pThis->m_nPresetNodeBits/8 > nContentLen || nContentLen == 0 )
	{
		pThis->m_bActive = 0;
		return 0;
	}

	pThis->m_nContentBitLen = pThis->m_nPresetNodeBits;

	if( pThis->fnPostDecompose )
	{
		if( ! pThis->fnPostDecompose( pThis ) )
			return -1;
	}

	return pThis->m_nPresetNodeBits;
}

MXD_INT32 ContainerDecompose( CMMBUNIT_DEFINE* pThis, MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_UINT32 nStartBit  )
{
	CMMBUNIT_DEFINE *pSubNode;
	MXD_UINT8* pCrtCnt = pContent;
	MXD_INT32 nCrtBit = (MXD_INT32) nStartBit;
	MXD_INT32 nEatenBits;
	MXD_INT32 nRestContentLen = nContentLen;

	if( nContentLen == 0 )
	{
		pThis->m_bActive = 0;
		return 0;
	}

	if( !pThis->m_bActive )
		return 0;

	pThis->m_pContent = pCrtCnt;
	pThis->m_nContentBitLen = 0;

	if( pThis->fnPreDecompose )
	{
		if( ! pThis->fnPreDecompose( pThis ) )
			return -1;
	}

	// predecompse may change the active flag.
	if( !pThis->m_bActive )
		return 0;

	if( pThis->m_u1.m_pChildUnitList )
	{
		pSubNode=pThis->m_u1.m_pChildUnitList;
		while( pSubNode->m_szNodeName )
		{
			if( !pSubNode->m_bActive )
			{
				if( !(pSubNode+1)->m_szNodeName && (pSubNode+1)->m_u2.m_pNextUnitList )
					pSubNode = (pSubNode+1)->m_u2.m_pNextUnitList;
				else
					pSubNode++;
				continue;
			}

			pSubNode->m_pContent = pCrtCnt;
			nEatenBits = pSubNode->fnDecompose( pSubNode, pCrtCnt, nRestContentLen, nCrtBit );
			if( nEatenBits < 0 )
				return -1;
			else
				pThis->m_nContentBitLen += pSubNode->m_nContentBitLen;

			nCrtBit += nEatenBits;
			if( nCrtBit >= 8 )
			{
				nRestContentLen -= nCrtBit/8;
				if( nRestContentLen<0 )
					nRestContentLen = 0;
				pCrtCnt += nCrtBit/8;
				nCrtBit = nCrtBit%8;
			}

			if( !(pSubNode+1)->m_szNodeName && (pSubNode+1)->m_u2.m_pNextUnitList )
				pSubNode = (pSubNode+1)->m_u2.m_pNextUnitList;
			else
				pSubNode++;
		}
		//when preset bits is not matched to parsing result, we must move parsing pointer to make sure further parsing is fine.
		if( pThis->m_nPresetNodeBits != 0 && pThis->m_nPresetNodeBits != pThis->m_nContentBitLen )
		{
			nCrtBit -= pThis->m_nContentBitLen - pThis->m_nPresetNodeBits;
			pCrtCnt += nCrtBit/8;
			nCrtBit = nCrtBit%8;
			pThis->m_nContentBitLen = pThis->m_nPresetNodeBits;
		}
	}

	if( pThis->fnPostDecompose )
	{
		if( ! pThis->fnPostDecompose( pThis ) )
			return -1;
	}

	return (MXD_INT32)((pCrtCnt - pContent)*8 + nCrtBit);
}

//void PrintCmmbUnit( CMMBUNIT_DEFINE* pUnit );
/****************************************************************************************************/

CMMBUNIT_DEFINE* FrameDecompose( MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_INT32 *pEatenBit  )
{
	CMMBUNIT_DEFINE* pTopFrameList = CloneUnitList(CmmbTopFrame);
	CMMBUNIT_DEFINE TopFrameCtn = *CmmbEmpty;

	if( !pTopFrameList )
		return NULL;
	TopFrameCtn.m_u1.m_pChildUnitList = pTopFrameList;
	if( (*pEatenBit = ContainerDecompose( &TopFrameCtn, pContent, nContentLen, 0 )) > 0 )
		return pTopFrameList;
	else
	{
		//PrintCmmbUnit( pTopFrameList );
		return NULL;
	}
}

CMMBUNIT_DEFINE* FrameHeaderDecompose( MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_INT32 *pEatenBit  )
{
	CMMBUNIT_DEFINE* pTopFrameList = CloneUnitList(CmmbFrameHeader);
	CMMBUNIT_DEFINE TopFrameCtn = *CmmbEmpty;

	TopFrameCtn.m_u1.m_pChildUnitList = pTopFrameList;
	if( (*pEatenBit = ContainerDecompose( &TopFrameCtn, pContent, nContentLen, 0 )) > 0 )
		return pTopFrameList;
	else
		return NULL;
}

CMMBUNIT_DEFINE* SubFrameDecompose( MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_INT32 *pEatenBit  )
{
	CMMBUNIT_DEFINE* pTopFrameList = CloneUnitList(CmmbSubFrame);
	CMMBUNIT_DEFINE TopFrameCtn = *CmmbEmpty;

	TopFrameCtn.m_u1.m_pChildUnitList = pTopFrameList;
	if( (*pEatenBit = ContainerDecompose( &TopFrameCtn, pContent, nContentLen, 0 )) > 0 )
		return pTopFrameList;
	else
	{
		//PrintCmmbUnit( pTopFrameList );
		return NULL;
	}
}

CMMBUNIT_DEFINE* EmgMsgDecompose( MXD_UINT8* pContent, MXD_UINT32 nContentLen, MXD_INT32 *pEatenBit  )
{
	CMMBUNIT_DEFINE* pTopFrameList = CloneUnitList(CmmbEmergencyMsg);
	CMMBUNIT_DEFINE TopFrameCtn = *CmmbEmpty;

	TopFrameCtn.m_u1.m_pChildUnitList = pTopFrameList;
	if( (*pEatenBit = ContainerDecompose( &TopFrameCtn, pContent, nContentLen, 0 )) > 0 )
		return pTopFrameList;
	else
		return NULL;
}

/****************************************************************************************************/

MXD_BOOL FrameHeader_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFrameHeader, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL FrameHeader_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis->m_u1.m_pChildUnitList+4 /*MF_ID*/ )->m_nValue == 0 )
	{
		( pThis+2 /*SubFrames*/ )->m_bActive = FALSE;
		( pThis+1 /*ControlTables*/ )->m_bActive = TRUE;
	}
	else
	{
		( pThis+1 /*ControlTables*/ )->m_bActive = FALSE;
		( pThis+2 /*SubFrames*/ )->m_bActive = TRUE;
	}
	return TRUE;
}

MXD_BOOL SubFramesLength_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-1 /*SubFrameCount*/ )->m_nValue ) 
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSubFrameLength, (pThis - 1 /*SubFrameCount*/)->m_nValue, pThis)))
			return FALSE;
	}
	return TRUE;
}

MXD_BOOL NextFrameParam_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-12 /*NextFrameIdc*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbNextFrameParam, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL FrameHeader_Verify( CMMBUNIT_DEFINE* pThis )
{
	return pThis->m_nValue == _mxd_CalcCRC32( (pThis-19/*FrameStartCode*/)->m_pContent, (MXD_INT32)(pThis->m_pContent - (pThis-19/*FrameStartCode*/)->m_pContent) );
}

MXD_BOOL StartTimeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-7 /*StartTimeFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbStartTime, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL VideoSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-7 /*VideoSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoSectionsInfo, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL AudioSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-7 /*AudioSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioSectionsInfo, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL DataSectionsInfoCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-7 /*DataSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDataSectionsInfo, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL VideoInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ! ( pThis-7 /*ExpandAreaFlag*/ )->m_nValue )
	{
		pThis->m_bActive = FALSE;
		return TRUE;
	}
	if( !( pThis-3 /*VideoSectionsInfoCtn*/ )->m_bActive )
	{
		pThis->m_bActive = FALSE;
		return TRUE;
	}
	if( !( pThis-3 /*VideoSectionsInfoCtn*/ )->m_u1.m_pChildUnitList )
		pThis->m_bActive = FALSE;
	else if( ( ( pThis-3 /*VideoSectionsInfoCtn*/ )->m_u1.m_pChildUnitList+1 /*VideoStreamCount*/ )->m_nValue == 0 )
		pThis->m_bActive = FALSE;
	else if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoInfo, ((pThis - 3 /*VideoSectionsInfoCtn*/)->m_u1.m_pChildUnitList + 1 /*VideoStreamCount*/)->m_nValue, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL AudioInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ! ( pThis-8 /*ExpandAreaFlag*/ )->m_nValue )
	{
		pThis->m_bActive = FALSE;
		return TRUE;
	}
	if( ! ( pThis-3 /*AudioSectionsInfoCtn*/ )->m_bActive )
	{
		pThis->m_bActive = FALSE;
		return TRUE;
	}
	if( ! ( pThis-3 /*AudioSectionsInfoCtn*/ )->m_u1.m_pChildUnitList )
		pThis->m_bActive = FALSE;
	else if( ( ( pThis-3 /*AudioSectionsInfoCtn*/ )->m_u1.m_pChildUnitList+1 /*AudioStreamCount*/ )->m_nValue == 0 )
		pThis->m_bActive = FALSE;
	else if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioInfo, ((pThis - 3 /*AudioSectionsInfoCtn*/)->m_u1.m_pChildUnitList + 1 /*AudioStreamCount*/)->m_nValue, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL VideoSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
#ifndef USE_EXTERNAL_DEMUXER
	if( ( pThis-13 /*VideoSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoSection, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
#endif //USE_EXTERNAL_DEMUXER
	return TRUE;
}

MXD_BOOL AudioSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
#ifndef USE_EXTERNAL_DEMUXER
	if( ( pThis-13 /*AudioSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioSection, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
#endif //USE_EXTERNAL_DEMUXER
	return TRUE;
}

MXD_BOOL DataSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
#ifndef USE_EXTERNAL_DEMUXER
	if( ( pThis-13 /*DataSectionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDataSection, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
#endif //USE_EXTERNAL_DEMUXER
	return TRUE;
}

MXD_BOOL BitRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-5 /*BitRateFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoBitRate, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL DisplayCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-5 /*DisplayFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDisplay, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL ResolutionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-5 /*ResolutionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbResolution, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL FrameRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-5 /*FrameRateFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFrameRate, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL AudioBitRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-4 /*BitRateFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioBitRate, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL SampleRateCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-4 /*SampleRateFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSampleRate, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL DescriptionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-4 /*DescriptionFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDescription, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL SubFrames_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT nSubFrameCount = ((pThis-2/*FrameHeader*/)->m_u1.m_pChildUnitList+16/*SubFrameCount*/)->m_nValue;
	MXD_INT i;
	if( nSubFrameCount )
	{
		CMMBUNIT_DEFINE* pSubFrameLength = ((pThis-2/*FrameHeader*/)->m_u1.m_pChildUnitList+17/*SubFramesLengthCtn*/)->m_u1.m_pChildUnitList;
		for( i=nSubFrameCount-1; i>=0; i-- )
		{
			if( pSubFrameLength->m_nValue == 0 )
				nSubFrameCount--;
			pSubFrameLength = GetNextSiblingInList(pSubFrameLength);
		}
		if (nSubFrameCount == 0 || (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSubFrame, nSubFrameCount, pThis))))
			return FALSE;
	}
	return TRUE;
}

MXD_BOOL ControlTables_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ((pThis-1/*FrameHeader*/)->m_u1.m_pChildUnitList+16/*SubFrameCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbControlTab, ((pThis - 1/*FrameHeader*/)->m_u1.m_pChildUnitList + 16/*SubFrameCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL SubFrameHeader_Verify( CMMBUNIT_DEFINE* pThis )
{
	return pThis->m_nValue == _mxd_CalcCRC32( (pThis-14/*SubFrameHeaderLength*/)->m_pContent, (MXD_INT32)(pThis->m_pContent - (pThis-14/*SubFrameHeaderLength*/)->m_pContent) );
}

MXD_BOOL NIT_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT8 i;
	MXD_UINT32 nSubFrameLen;
	for( i=0; i<9; i++ )
		(pThis+i)->m_bActive = FALSE;

	//check crc before further parsing.
	nSubFrameLen = GetUnitFromLinkedUnitList( ((pThis->m_u2.m_pParentUnit-1 /*FrameHeader*/)->m_u1.m_pChildUnitList + 17 /*SubFramesLengthCtn*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "SubFrameLength" )->m_nValue;
	if( 0 != _mxd_CalcCRC32( pThis->m_pContent, nSubFrameLen ) )
	{
		(pThis+8)->m_bActive = TRUE;
		(pThis+8)->m_nPresetNodeBits = nSubFrameLen*8;
		return TRUE;
	}

	switch( *pThis->m_pContent )
	{
	case 0x01: /*NIT*/
		pThis->m_bActive = TRUE;
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbNIT, 1, pThis)))
			return FALSE;
		pThis->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x02: /*CMCT*/
		(pThis+1)->m_bActive = TRUE;
		if (NULL == ((pThis + 1)->m_u1.m_pChildUnitList = CreateUnitList(CmmbCMCT_SMCT, 1, pThis + 1)))
			return FALSE;
		(pThis+1)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x03: /*CSCT*/
		(pThis+2)->m_bActive = TRUE;
		if (NULL == ((pThis + 2)->m_u1.m_pChildUnitList = CreateUnitList(CmmbCSCT_SSCT, 1, pThis + 2)))
			return FALSE;
		(pThis+2)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x04: /*SMCT*/
		(pThis+3)->m_bActive = TRUE;
		if (NULL == ((pThis + 3)->m_u1.m_pChildUnitList = CreateUnitList(CmmbCMCT_SMCT, 1, pThis + 3)))
			return FALSE;
		(pThis+4)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x05: /*SSCT*/
		(pThis+4)->m_bActive = TRUE;
		if (NULL == ((pThis + 4)->m_u1.m_pChildUnitList = CreateUnitList(CmmbCSCT_SSCT, 1, pThis + 4)))
			return FALSE;
		(pThis+5)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x06: /*ESGTab*/
		(pThis+5)->m_bActive = TRUE;
		if (NULL == ((pThis + 5)->m_u1.m_pChildUnitList = CreateUnitList(CmmbESGTab, 1, pThis + 5)))
			return FALSE;
		(pThis+5)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x07: /*CASTab*/
		(pThis+6)->m_bActive = TRUE;
		if (NULL == ((pThis + 6)->m_u1.m_pChildUnitList = CreateUnitList(CmmbCASTab, 1, pThis + 6)))
			return FALSE;
		(pThis+6)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	case 0x10: /*EmergencyTab*/
		(pThis+7)->m_bActive = TRUE;
		if (NULL == ((pThis + 7)->m_u1.m_pChildUnitList = CreateUnitList(CmmbEmergencyTab, 1, pThis + 7)))
			return FALSE;
		(pThis+7)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	default: /*Unknown Data*/
		(pThis+8)->m_bActive = TRUE;
		(pThis+8)->m_nPresetNodeBits = nSubFrameLen*8;
		break;
	}
	return TRUE;
}

MXD_BOOL SystemTime_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSystemTime, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL NetName_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (0 == (pThis->m_nPresetNodeBits = (pThis - 1/*NetNameLength*/)->m_nValue * 8))
		return FALSE;
	return TRUE;
}

MXD_BOOL OtherFreqInfo_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*FreqCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbOtherFreqInfo, (pThis - 1/*FreqCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL OtherNetInfo_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-2/*OtherNetInfo*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbOtherNetInfo, (pThis - 2/*OtherNetInfo*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ServiceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ServiceInfoCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbServiceInfo, (pThis - 1/*ServiceInfoCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL TimeSlots_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*TimeSlotCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbTimeSlot, (pThis - 1/*TimeSlotCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL SubFramesInfo_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*SubFrameCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSubFrameInfo, (pThis - 1/*SubFrameCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ShortServiceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ShortServiceInfoCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbShortServiceInfo, (pThis - 1/*ShortServiceInfoCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ESGSeviceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ESGSeviceCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbESGSeviceInfo, (pThis - 1/*ESGSeviceCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ESGDataTypes_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ESGDataTypeCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbESGDataType, (pThis - 1/*ESGDataTypeCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ESGDataSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ESGDataSliceCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbESGDataSliceInfo, (pThis - 1/*ESGDataSliceCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL CAS_SectionInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*SectionQuantity*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbCAS_SectionInfo, (pThis - 1/*SectionQuantity*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL EmergencyMsgSectionCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbEmergencyMsgSection, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL EmergencyMsgData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*MsgLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL EmergencyMsgData_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nEmergencyMsgLength = ( pThis->m_u2.m_pParentUnit-1 /*EmergencyMsgSectionLength*/ )->m_nValue;

	//if we have not reach the end of section header.
	if( nEmergencyMsgLength > pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_pContent + pThis->m_nPresetNodeBits/8 )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbEmergencyMsgSection, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbEmergencyMsgSection)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 9/*Header at ProtocolVer*/;
	}
	return TRUE;
}

MXD_BOOL EmergencyMsgBodyCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent & 0x80 )
	{
		pThis->m_bActive = FALSE;
		(pThis+1/*EmergencyMsgTrigerCtn*/)->m_bActive = TRUE;
		if (NULL == ((pThis + 1/*EmergencyMsgTrigerCtn*/)->m_u1.m_pChildUnitList = CreateUnitList(CmmbEmergencyMsgTriger, 1, pThis + 1/*EmergencyMsgTrigerCtn*/)))
			return FALSE;
	}
	else
	{
		pThis->m_bActive = TRUE;
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbEmergencyMsgBody, 1, pThis)))
			return FALSE;
		(pThis+1/*EmergencyMsgTrigerCtn*/)->m_bActive = FALSE;
	}
	return TRUE;
}

MXD_BOOL EmgSendTime_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSystemTime, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL MsgDetailCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*LangCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbMsgDetail, (pThis - 1/*LangCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ExtendMsgs_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-1/*ExtendMsgCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbExtendEmergencyMsg, (pThis - 1/*ExtendMsgCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ExtendMsgData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*DataLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL MsgText_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*TextLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL InstitutionName_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*NameLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL InstitutionDetailCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-5 /*InstitutionFlag*/)->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbInstitutionDetail, 1, pThis)))
			return FALSE;
	}
	else
	{
		pThis->m_bActive = FALSE;
	}
	return TRUE;
}

MXD_BOOL ReferenceServiceIdc_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-5 /*ReferenceServiceFlag*/)->m_nValue )
		pThis->m_bActive = TRUE;
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL CmmbXpe_Start_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent != 0x55 )
	{
		pThis->m_bActive = FALSE;
		(pThis+1/*InnoEndIdc*/)->m_bActive = FALSE;
		(pThis+2/*InnoPacketType*/)->m_bActive = FALSE;
		(pThis+3/*InnoPacketLen*/)->m_bActive = FALSE;
		(pThis+4/*InnoCrc8*/)->m_bActive = FALSE;
		(pThis+5/*UnknownFlag*/)->m_bActive = FALSE;
		(pThis+8/*CRC32*/)->m_bActive = FALSE;
	}
	return TRUE;
}

MXD_BOOL TotalPacketLen_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-7 /*StartFlag*/)->m_nValue == 1 && (pThis-6 /*EndFlag*/)->m_nValue == 0 )
		pThis->m_bActive = TRUE;
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL PayloadTypeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-7 /*StartFlag*/)->m_nValue == 1 && (pThis-5 /*IsFecIdc*/)->m_nValue == 0 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbPayloadType, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}


#ifndef USE_EXTERNAL_DEMUXER

MXD_BOOL VideoSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoSliceInfo, 1, pThis)))
		return FALSE;

	return TRUE;
}

MXD_BOOL VideoPlayTimeCtn_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT32 nVideoSectionHeaderLength = ( pThis->m_u2.m_pParentUnit-2 /*VideoSectionHeaderLength*/ )->m_nValue;

	//if we have not reach the end of section header.
	if( nVideoSectionHeaderLength > pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_pContent + 2 )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbVideoSliceInfo, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbVideoSliceInfo)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 5/*Header at VideoSliceLength*/;
	}
	return TRUE;
}

MXD_BOOL InnoVideoPackets_PreDecompose(CMMBUNIT_DEFINE* pThis)
{
	if (*pThis->m_pContent != 0x55)
		pThis->m_bActive = FALSE;
	else if (GetLinkedUnitListCount((pThis - 2 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList))
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbInnoVideoPacket, GetLinkedUnitListCount((pThis - 2 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList), pThis)))
			return FALSE;
	}
	return TRUE;
}

MXD_BOOL RawVideoSlices_PreDecompose(CMMBUNIT_DEFINE* pThis)
{
	if ((pThis - 1/*InnoVideoPackets*/)->m_bActive)
		pThis->m_bActive = FALSE;
	else if (GetLinkedUnitListCount((pThis - 3 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList))
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbRawVideoSlice, GetLinkedUnitListCount((pThis - 3 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList), pThis)))
			return FALSE;
	}
	return TRUE;
}

MXD_BOOL InnoVideoFragment_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbInnoVideoFragment, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL RawVideoSlice_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit - 3 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "VideoSliceLength" )->m_nValue * 8;
	return TRUE;
}

MXD_BOOL PlayTimeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( ( pThis-1 /*PlayTimeFlag*/ )->m_nValue )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoPlayTime, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL VideoAuHeader_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent == 0 && *(pThis->m_pContent+1) == 0x2a )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbVideoAuHeader, 1, pThis)))
			return FALSE;
		(pThis+1/*Forbidden_zero_bit*/)->m_bActive = FALSE;
		(pThis+2/*Nal_ref_idc*/)->m_bActive = FALSE;
		(pThis+3/*Type*/)->m_bActive = FALSE;
	}
	return TRUE;
}

MXD_BOOL AudioAuHeader_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent == 0 && *(pThis->m_pContent+1) == 0x38 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioAuHeader, 1, pThis)))
			return FALSE;
	}
	return TRUE;
}

MXD_BOOL AudioNewHeader_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent == 0 && *(pThis->m_pContent+1) == 0x10 )
	{
		//if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioNewHeader, 1, pThis)))
		//	return FALSE;
	}
	return TRUE;
}

MXD_BOOL RtpNalPacketCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT32 nVideoType = (pThis-1/*Type*/ )->m_nValue;
	if( nVideoType >=0 && nVideoType <= 23 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbH264Packet, 1, pThis)))
			return FALSE;
	}
	else if( nVideoType == 24 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSTAP_A_Packet, 1, pThis)))
			return FALSE;
	}
	else if( nVideoType == 28 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFU_A_Packet, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL RtpNalPacketCtn_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nVideoPacketIndex = FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis->m_u2.m_pParentUnit );
	MXD_UINT32 nCurrentVideoSliceLen = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit - 2 /*VideoSliceInfos*/)->m_u1.m_pChildUnitList, nVideoPacketIndex, "VideoSliceLength" )->m_nValue; 

	//if we have not reach the end of current video packet.
	if( pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent + pThis->m_nContentBitLen/8 < nCurrentVideoSliceLen )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbInnoVideoFragment, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbInnoVideoFragment)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 9/* header at InnoStartByte*/;
	}
	return TRUE;
}

MXD_BOOL RawH264_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = ((pThis->m_u2.m_pParentUnit - 6 /*InnoPacketLen*/ )->m_nValue - 1) * 8;
	if( (pThis->m_u2.m_pParentUnit - 4 /*VideoAuHeader*/ )->m_u1.m_pChildUnitList )
		pThis->m_nPresetNodeBits -= 8*8 - 8;
	return TRUE;
}

MXD_BOOL NalUnitData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis - 1 /*NalUnitSize*/ )->m_nValue * 8;
	return TRUE;
}

MXD_BOOL NalUnitData_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT32 nInnoPacketLen = (pThis->m_u2.m_pParentUnit - 6 /*InnoPacketLen*/ )->m_nValue;

	//if we have not reach the end of packet.
	if( nInnoPacketLen > pThis->m_nPresetNodeBits/8 + pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent + 1 )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbSTAP_A_Packet, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbSTAP_A_Packet)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 1/*header at NalUnitSize*/;
	}
	return TRUE;
}

MXD_BOOL FU_Data_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = ((pThis->m_u2.m_pParentUnit - 6 /*InnoPacketLen*/ )->m_nValue - 2 ) * 8;
	return TRUE;
}

MXD_BOOL AudioSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis - 1 /*AudioSliceCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbAudioSliceInfo, (pThis - 1 /*AudioSliceCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL AudioSectionHeader_Verify( CMMBUNIT_DEFINE* pThis )
{
	if( pThis->m_nValue != _mxd_CalcCRC32( pThis->m_u2.m_pParentUnit->m_pContent, (MXD_INT32)(pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent) ) )
	{
		pThis->m_u2.m_pParentUnit->m_bActive = FALSE;
		MXD_DebugPrint( "Audio header crc fail!\n" );
		//PrintCmmbUnit( pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit );
	}
	return TRUE;
}

MXD_BOOL RawAudioSize_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	//when header is 0xff, the first two byte is aac length, and if header is 0xffff, the first 3 byte is length!
	if( (*pThis->m_pContent) == 0xff && (*(pThis->m_pContent+1)) == 0xff )
		pThis->m_nPresetNodeBits = 24;
	else if( (*pThis->m_pContent) == 0xff )
		pThis->m_nPresetNodeBits = 16;
	else if( (*pThis->m_pContent) == 0 ) //DRA audio!
		pThis->m_nPresetNodeBits = 0;
	else
		pThis->m_nPresetNodeBits = 8;
	return TRUE;
}

MXD_BOOL RawAudioSize_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	//when header is 0xff, the first two byte is aac length, and if header is 0xffff, the first 3 byte is length!
	if( (*pThis->m_pContent) == 0xff && (*(pThis->m_pContent+1)) == 0xff )
	{
		pThis->m_nValue &= 0x1ff;
		pThis->m_nValue += 0x100;
		pThis->m_nValue -= 2;
	}
	else if( (*pThis->m_pContent) == 0xff )
	{
		pThis->m_nValue &= 0x1ff;
		pThis->m_nValue --;
	}

	if( (*pThis->m_pContent) == 0 ) //DRA audio!
	{
		pThis->m_nValue = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-3 /*AudioSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis->m_u2.m_pParentUnit ), "AudioSliceLength" )->m_nValue;;
		return TRUE;
	}

	return TRUE;
}

MXD_BOOL InnoAudioPacket_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent != 0x55 )
		pThis->m_bActive = FALSE;
	else if( (pThis - 3 /*AudioSliceCount*/)->m_nValue == 0 )
		pThis->m_bActive = FALSE;
	else if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbInnoAudioPacket, (pThis - 3 /*AudioSliceCount*/)->m_nValue, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL RawAacCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbRawAac_Packet, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL RawAacSize_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if(  (pThis->m_u2.m_pParentUnit - 2 /*AudioAuHeader*/ )->m_u1.m_pChildUnitList )
		return TRUE;
	if(  (pThis->m_u2.m_pParentUnit - 1 /*AudioNewHeader*/ )->m_u1.m_pChildUnitList )
	{
		pThis->m_nPresetNodeBits = 0;
		return TRUE;
	}
	if( (*pThis->m_pContent) == 0 )
	{
		pThis->m_nPresetNodeBits = 0;
		return TRUE;
	}

	//when header is 0xff, the first two byte is aac length, and if header is 0xffff, the first 3 byte is length!
	if( (*pThis->m_pContent) == 0xff && (*(pThis->m_pContent+1)) == 0xff )
		pThis->m_nPresetNodeBits = 24;
	else if( (*pThis->m_pContent) == 0xff )
		pThis->m_nPresetNodeBits = 16;
	else
		pThis->m_nPresetNodeBits = 8;
	return TRUE;
}

MXD_BOOL RawAacSize_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	if(  (pThis->m_u2.m_pParentUnit - 2 /*AudioAuHeader*/ )->m_u1.m_pChildUnitList )
	{
		pThis->m_nValue = (pThis->m_u2.m_pParentUnit - 4 /*InnoPacketLen*/ )->m_nValue - 9;
		return TRUE;
	}
	if(  (pThis->m_u2.m_pParentUnit - 1 /*AudioNewHeader*/ )->m_u1.m_pChildUnitList )
	{
		pThis->m_nValue = (pThis->m_u2.m_pParentUnit - 4 /*InnoPacketLen*/ )->m_nValue - 4;
		return TRUE;
	}
	if( (*pThis->m_pContent) == 0 )
	{
		pThis->m_nValue = (pThis->m_u2.m_pParentUnit - 4 /*InnoPacketLen*/ )->m_nValue;
		return TRUE;
	}

	//when header is 0xff, the first two byte is aac length, and if header is 0xffff, the first 3 byte is length!
	if( (*pThis->m_pContent) == 0xff && (*(pThis->m_pContent+1)) == 0xff )
	{
		pThis->m_nValue &= 0x1ff;
		pThis->m_nValue += 0x100;
		pThis->m_nValue -= 2;
	}
	else if( (*pThis->m_pContent) == 0xff )
	{
		pThis->m_nValue &= 0x1ff;
		pThis->m_nValue --;
	}

	return TRUE;
}

MXD_BOOL RawAacData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = ((pThis - 1 /*RawAacSize*/ )->m_nValue ) * 8;

	if( !( (pThis->m_u2.m_pParentUnit - 2 /*AudioAuHeader*/ )->m_u1.m_pChildUnitList || (pThis->m_u2.m_pParentUnit - 1 /*AudioNewHeader*/ )->m_u1.m_pChildUnitList ) )
	{
		MXD_INT32 nInnoPacketLen;

		nInnoPacketLen = (pThis->m_u2.m_pParentUnit - 4 /*InnoPacketLen*/ )->m_nValue;

		//we must not extend the end of packet.
		if( nInnoPacketLen + pThis->m_u2.m_pParentUnit->m_pContent < pThis->m_nPresetNodeBits/8 + pThis->m_pContent  )
		{
			pThis->m_nPresetNodeBits = (nInnoPacketLen - ( pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent ) ) * 8;
		}
	}
	return TRUE;
}

MXD_BOOL RawAacData_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT32 nInnoPacketLen;

	if(  (pThis->m_u2.m_pParentUnit - 2 /*AudioAuHeader*/ )->m_u1.m_pChildUnitList || (pThis->m_u2.m_pParentUnit - 1 /*AudioNewHeader*/ )->m_u1.m_pChildUnitList )
	{
		return TRUE;
	}

	nInnoPacketLen = (pThis->m_u2.m_pParentUnit - 4 /*InnoPacketLen*/ )->m_nValue - 1;

	//if we have not reach the end of packet.
	if( nInnoPacketLen > pThis->m_nPresetNodeBits/8 + pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent + 1 )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbRawAac_Packet, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbRawAac_Packet)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 1/*header at RawAacSize*/;
	}
	return TRUE;
}

MXD_BOOL RawAudioSlices_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis - 1/*InnoAudioPacket*/)->m_bActive )
		pThis->m_bActive = FALSE;
	else if( (pThis - 4 /*AudioSliceCount*/)->m_nValue == 0 )
		pThis->m_bActive = FALSE;
	else if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbRawAudioPacket, (pThis - 4 /*AudioSliceCount*/)->m_nValue, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL RawAudioCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbRawAudioSlice, 1, pThis)))
		return FALSE;
	return TRUE;
}


MXD_BOOL RawAudio_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = ((pThis - 1 /*RawAudioSize*/ )->m_nValue ) * 8;
	return TRUE;
}

MXD_BOOL VideoCrc8_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( _mxd_CalcCRC8( pThis->m_pContent - 3, 4 ) != 0 )
	{
		CMMBUNIT_DEFINE* pVideoPacket = pThis->m_u2.m_pParentUnit;
		CMMBUNIT_DEFINE* pVideoSliceInfos = pVideoPacket->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_u1.m_pChildUnitList + 2;
		CMMBUNIT_DEFINE* pVideoSlices = pVideoPacket->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_u1.m_pChildUnitList + 4;
		MXD_INT32 nVideoIndex = FindMyIndexFromLinkedUnitList( pVideoSlices->m_u1.m_pChildUnitList, pVideoPacket );
		MXD_INT32 nVideoSliceLen = GetUnitFromLinkedUnitList( pVideoSliceInfos->m_u1.m_pChildUnitList, nVideoIndex, "VideoSliceLength" )->m_nValue;
		(pThis-1/*InnoPacketLen*/)->m_nValue = nVideoSliceLen - 4;
	}
	return TRUE;
}

MXD_BOOL AudioCrc8_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( _mxd_CalcCRC8( pThis->m_pContent - 3, 4 ) != 0 )
	{
		CMMBUNIT_DEFINE* pAudioPacket = pThis->m_u2.m_pParentUnit;
		CMMBUNIT_DEFINE* pAudioSliceInfos = pAudioPacket->m_u2.m_pParentUnit->m_u1.m_pChildUnitList + 1;
		CMMBUNIT_DEFINE* pAudioSlices = pAudioPacket->m_u2.m_pParentUnit->m_u1.m_pChildUnitList + 3;
		MXD_INT32 nAudioIndex = FindMyIndexFromLinkedUnitList( pAudioSlices->m_u1.m_pChildUnitList, pThis-4 );
		MXD_INT32 nAudioSliceLen = GetUnitFromLinkedUnitList( pAudioSliceInfos->m_u1.m_pChildUnitList, nAudioIndex, "AudioSliceLength" )->m_nValue;
		(pThis-1/*InnoPacketLen*/)->m_nValue = nAudioSliceLen - 4;
	}
	return TRUE;
}

MXD_BOOL RawAudio_PostDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_INT32 nAudioSliceLen = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-3 /*AudioSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis->m_u2.m_pParentUnit ), "AudioSliceLength" )->m_nValue;

	//if we have not reach the end of packet.
	if( nAudioSliceLen > pThis->m_nPresetNodeBits/8 + pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent )
	{
		//create new node list, which linked after us.
		if (NULL == ((pThis + 1)->m_u2.m_pNextUnitList = CreateUnitList(CmmbRawAudioSlice, 1, pThis->m_u2.m_pParentUnit)))
			return FALSE;
		( (pThis+1)->m_u2.m_pNextUnitList + sizeof(CmmbRawAudioSlice)/sizeof(CMMBUNIT_DEFINE) - 1 )->m_u1.m_pPrevUnitList = pThis - 1/*header at RawAudioSize*/;
	}
	return TRUE;
}

MXD_BOOL DataSliceInfos_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis - 1 /*DataSliceCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDataSliceInfo, (pThis - 1 /*DataSliceCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL DataSectionHeader_Verify( CMMBUNIT_DEFINE* pThis )
{
	if( pThis->m_nValue != _mxd_CalcCRC32( pThis->m_u2.m_pParentUnit->m_pContent, (MXD_INT32)(pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent) ) )
	{
		pThis->m_u2.m_pParentUnit->m_bActive = FALSE;
		MXD_DebugPrint( "Data header crc fail!\n" );
		//PrintCmmbUnit( pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit );
	}
	return TRUE;
}

MXD_BOOL DataSlices_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis - 3 /*DataSliceCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbDataSlice, (pThis - 3 /*DataSliceCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL ProgramHint_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nDataType = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit-2 /*DataSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "DataSliceType" )->m_nValue;
	if( nDataType == 1 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbProgramHint, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL EsgDataSection_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nDataType = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit-2 /*DataSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "DataSliceType" )->m_nValue;
	if( nDataType == 0 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbEsgDataSection, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL XpeDataSection_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nDataType = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit-2 /*DataSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "DataSliceType" )->m_nValue;
	if( nDataType == 160 || nDataType == 161 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbXpePacket, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL OtherDataSlice_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 nDataType = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit-2 /*DataSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "DataSliceType" )->m_nValue;
	if( nDataType != 0 && nDataType != 1 && nDataType != 160 && nDataType != 161 )
		pThis->m_nPresetNodeBits = GetUnitFromLinkedUnitList( (pThis->m_u2.m_pParentUnit-2 /*DataSliceInfos*/)->m_u1.m_pChildUnitList, FindMyIndexFromLinkedUnitList( pThis->m_u2.m_pParentUnit->m_u1.m_pChildUnitList, pThis ), "DataSliceLength" )->m_nValue * 8;
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL CmmbProgramHint_Start_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent != 0x55 )
	{
		pThis->m_bActive = FALSE;
		(pThis+1/*InnoEndIdc*/)->m_bActive = FALSE;
		(pThis+2/*InnoPacketType*/)->m_bActive = FALSE;
		(pThis+3/*InnoPacketLen*/)->m_bActive = FALSE;
		(pThis+4/*InnoCrc8*/)->m_bActive = FALSE;
		(pThis+5/*UnknownFlag*/)->m_bActive = FALSE;
		(pThis+9/*CRC32*/)->m_bActive = FALSE;
	}
	return TRUE;
}

MXD_BOOL ProgramHintRecords_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-2/*RecordCount*/)->m_nValue )
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbProgramHintRecord, (pThis - 2/*RecordCount*/)->m_nValue, pThis)))
			return FALSE;
	return TRUE;
}

MXD_BOOL HintStartTime_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbSystemTime, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL ProgramHintSubject_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*SubjectLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL InnoEsgDataHeader_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( *pThis->m_pContent == 0x55 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbInnoEsgDataHeader, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL EsgDataSlice_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	MXD_UINT32 i, nCrc = -1;
	if( (pThis-1/*SliceLength*/)->m_nValue < pThis->m_nContentBitLen/8 )
	{
		nCrc = _mxd_CalcCRC32( pThis->m_u2.m_pParentUnit->m_pContent+5, (MXD_INT32)(pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent) + (pThis-1/*SliceLength*/)->m_nValue + 4 - 5 );
		if( nCrc != 0 )
		{
			MXD_UINT8 nCrc8;
			//this slice is wrong! try to found the next correct header after this.
			for( i=5; i<(pThis-1/*SliceLength*/)->m_nValue*2-1; i++ )
			{
				if( pThis->m_pContent[i] == 0x55 )
				{
					nCrc8 = _mxd_CalcCRC8( pThis->m_pContent + i, 5 );
					if( nCrc8 == 0 )
					{
						i-=4; // leave for CRC32
						pThis->m_nPresetNodeBits = i * 8;
						(pThis-1/*SliceLength*/)->m_nValue = i;
						return TRUE;
					}
				}
			}
		}
	}
	else
	{
		pThis->m_nPresetNodeBits = 0;
		return TRUE;
	}
	pThis->m_nPresetNodeBits = (pThis-1/*SliceLength*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL VideoSectionHeader_Verify( CMMBUNIT_DEFINE* pThis )
{
	if( pThis->m_nValue != _mxd_CalcCRC32( pThis->m_u2.m_pParentUnit->m_pContent, (MXD_INT32)(pThis->m_pContent - pThis->m_u2.m_pParentUnit->m_pContent) ) )
	{
		pThis->m_u2.m_pParentUnit->m_bActive = FALSE;
		MXD_DebugPrint( "Video header crc fail!\n" );
	}
	return TRUE;
}

MXD_BOOL FecTypeCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-7 /*StartFlag*/)->m_nValue == 1 && (pThis-5 /*IsFecIdc*/)->m_nValue == 1 )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFecType, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL XpePayloadCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbXpePayload, 1, pThis)))
		return FALSE;
	return TRUE;
}

MXD_BOOL XpePacket_Verify( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis-7/*CrcIdc*/)->m_nValue == 1 )
	{
		if( pThis->m_nValue != _mxd_CalcCRC32( (pThis-12/*StartFlag*/)->m_pContent, (MXD_INT32)(pThis->m_pContent - (pThis-12/*StartFlag*/)->m_pContent) ) )
			MXD_DebugPrint( "XpePacket crc fail!\n" );
	}
	return TRUE;
}

MXD_BOOL FecParam_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	pThis->m_nPresetNodeBits = (pThis-1/*FecParamLen*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL FecData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit-9/*IsFecIdc*/)->m_nValue != 1 )
	{
		pThis->m_nPresetNodeBits = 0;
		pThis->m_bActive = FALSE;
		return TRUE;
	}

	pThis->m_nPresetNodeBits = (pThis->m_u2.m_pParentUnit-7/*PayloadLen*/)->m_nValue * 8;
	return TRUE;
}

MXD_BOOL StreamData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit-9/*IsFecIdc*/)->m_nValue != 0 || !(pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_bActive)
	{
		pThis->m_nPresetNodeBits = 0;
		pThis->m_bActive = FALSE;
		return TRUE;
	}

	if( (pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_u1.m_pChildUnitList->m_nValue == 0 )
	{
		if( (pThis->m_u2.m_pParentUnit-4/*TotalPacketLen*/)->m_bActive )
			pThis->m_nPresetNodeBits = (pThis->m_u2.m_pParentUnit-4/*TotalPacketLen*/)->m_nValue * 8;
		else
			pThis->m_nPresetNodeBits = (pThis->m_u2.m_pParentUnit-7/*PayloadLen*/)->m_nValue * 8;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL FileSliceCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit-9/*IsFecIdc*/)->m_nValue != 0 || !(pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_bActive )
	{
		pThis->m_nPresetNodeBits = 0;
		pThis->m_bActive = FALSE;
		return TRUE;
	}

	if( (pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_u1.m_pChildUnitList->m_nValue == 1 && ( *pThis->m_pContent != 0 || *(pThis->m_pContent+1) != 0 ) )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFileSlice, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL FatSliceCtn_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit-9/*IsFecIdc*/)->m_nValue != 0 || !(pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_bActive )
	{
		pThis->m_nPresetNodeBits = 0;
		pThis->m_bActive = FALSE;
		return TRUE;
	}

	if( (pThis->m_u2.m_pParentUnit-3/*PayloadTypeCtn*/)->m_u1.m_pChildUnitList->m_nValue == 1 && ( *pThis->m_pContent == 0 && *(pThis->m_pContent+1) == 0 ) )
	{
		if (NULL == (pThis->m_u1.m_pChildUnitList = CreateUnitList(CmmbFatSlice, 1, pThis)))
			return FALSE;
	}
	else
		pThis->m_bActive = FALSE;
	return TRUE;
}

MXD_BOOL FileData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit -4/*TotalPacketLen*/)->m_bActive )
		pThis->m_nPresetNodeBits = (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-4/*TotalPacketLen*/)->m_nValue * 8;
	else
		pThis->m_nPresetNodeBits = ((pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-7/*PayloadLen*/)->m_nValue - 6 )* 8;
	return TRUE;
}

MXD_BOOL FatData_PreDecompose( CMMBUNIT_DEFINE* pThis )
{
	if( (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit -4/*TotalPacketLen*/)->m_bActive )
		pThis->m_nPresetNodeBits = (pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-4/*TotalPacketLen*/)->m_nValue * 8;
	else
		pThis->m_nPresetNodeBits = ((pThis->m_u2.m_pParentUnit->m_u2.m_pParentUnit-7/*PayloadLen*/)->m_nValue -11 )* 8;
	return TRUE;
}

#endif //USE_EXTERNAL_DEMUXER



/*****************************************************crc****************************/
/*
CRC-4            x4+x1+1                                             ITU G.704 
CRC-12           x12+x11+x3+x+1      
CRC-16           x16+x15+x2+1               0x8005                   IBM SDLC 
CRC-ITU          x16+x12+x5+1               0x1201                   ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS 
CRC-32           x32+x26+x23+...+x2+x+1     0x04C11DB7               ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS 
CRC-32c          x32+x28+x27+...+x8+x6+1    0x1EDC6F41               SCTP
*/
const MXD_INT32 MXD_CRC8_SEED		= 0x31;
const MXD_INT32 MXD_CRC16_SEED	= 0x8005;
const MXD_INT32 MXD_CRC32_SEED	= 0x04C11DB7;

static MXD_UINT32 _mxd_crc32_table[256];
static MXD_UINT8 _mxd_crc8_table[256];

void _mxd_BuildCrcTable(void);

MXD_UINT32 _mxd_CalcCRC32(const MXD_UINT8* inData, MXD_INT32 inLen)
{
	MXD_UINT32 dwRegister = 0xFFFFFFFF, i;
	if( _mxd_crc32_table[1] != 0x04c11db7 )
		_mxd_BuildCrcTable( );

	for( i=0; i<(MXD_UINT32)inLen; i++ )
		dwRegister = ((dwRegister) << 8) ^ _mxd_crc32_table[(inData[i]) ^ (dwRegister>>24)];

	return dwRegister;
}

/*
static unsigned short crc16_table[256]; // CRC table

unsigned short CalcCRC16(const MXD_UINT8* aData, MXD_INT32 aSize )
{
unsigned short nAccum = 0;

for (MXD_INT32 i = 0; i < aSize; i++ )
nAccum = ( nAccum << 8 ) ^ crc16_table[( nAccum >> 8 ) ^ aData[i]];
return nAccum;
}
*/

MXD_UINT8 _mxd_CalcCRC8(const MXD_UINT8* pbuf, MXD_INT32 len) 
{ 
	MXD_UINT8 crc = 0; 
	MXD_INT32 i;
	for( i=0; i < len; i++) 
	{ 
		crc = _mxd_crc8_table[crc ^ pbuf[i]]; 
	} 
	return crc; 
}

void _mxd_BuildCrcTable( )
{
	MXD_INT32 i,j;
	MXD_UINT32 nData;
	MXD_UINT32 nAccum;
	for( i = 0; i < 256; i++ )
	{
		nData = i;
		nAccum = 0;
		for ( j = 0; j < 8; j++ )
		{
			if ( ( nData ^ nAccum ) & 0x80 )
				nAccum = ( nAccum << 1 ) ^ MXD_CRC8_SEED;
			else
				nAccum <<= 1;
			nData <<= 1;
		}
		_mxd_crc8_table[i] = nAccum;
	}

	for ( i = 0; i < 256; i++ )
	{
		nData = ( MXD_UINT32 )( i << 24 );
		nAccum = 0;
		for ( j = 0; j < 8; j++ )
		{
			if ( ( nData ^ nAccum ) & 0x80000000 )
				nAccum = ( nAccum << 1 ) ^ MXD_CRC32_SEED;
			else
				nAccum <<= 1;
			nData <<= 1;
		}
		_mxd_crc32_table[i] = nAccum;
	}
}
